package com.arpgalaxy.spring.boot.autoconfigure.shiro;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @author arpgalaxy
 * @date 2020/10/13
 * @email 13605560342@163.com
 * @description
 */
public class ShiroAuthenticatingFilter extends AuthenticatingFilter {

    private ArpgalaxyShiroProperties properties;
    public  ShiroAuthenticatingFilter(ArpgalaxyShiroProperties properties){
        this.properties = properties;
    }
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        //获取请求token
        String token = getRequestToken((HttpServletRequest) request);

        if(token == null || token !=null && "null".equals(token) || token.isEmpty()){
            return null;
        }
        //TODO 可以进一步验证用户名密码，暂时先默认获取到token视为有登录权限，用户信息在realm里面获取
        return new ShiroAuthenticatingToken(token);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        System.out.println("filter   isAccessAllowed ");
        if("OPTIONS".equals(((HttpServletRequest)request).getMethod())){
            //options 请求直接放行
            return true;
        }
        //配置的不需要鉴权的UrlIgnoreList直接放行
        for (String url : properties.getUrlIgnoreList()){
            if (url !=null && url.equals(((HttpServletRequest)request).getServletPath())){
                return true;
            }
        }
        //非options 请求进入onAccessDenied进行登录验证
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        System.out.println("filter   onAccessDenied ");
        //获取请求token，如果token不存在，直接返回401
        String token = getRequestToken((HttpServletRequest) request);

        System.out.println(token);
        //obj=null && obj="" && obj="null"都视为空
        if(token == null || token !=null && "null".equals(token) || token.isEmpty()) {
            System.out.println("token   null ");
//            ObjectMapper mapper = new ObjectMapper();
//            //使用writeValueAsString()方法将Java对象解析成json格式
//            String result = mapper.writeValueAsString(new ResponseEntity<Throwable>(InkStatus.CORE_OK, "token is null", null));
            String result = "onAccessDenied token is null";
            response.getWriter().print(result);
            //直接返回数据,不执行过滤器链
            return false;
        }
        if (properties.getLogin()!=null && properties.getLogin().equals(((HttpServletRequest)request).getServletPath())){
            //shiro登录，进入realm,获取用户信息
            return executeLogin(request,response);
        }else{
            //直接放行，继续过滤器链
            return true;
        }


    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        System.out.println("filter   onLoginFailure ");
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setContentType("application/json;charset=utf-8");
//        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
//        httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
        try {
            //处理登录失败的异常
            e.printStackTrace();
            Throwable throwable = e.getCause() == null ? e : e.getCause();
//            ObjectMapper mapper = new ObjectMapper();
//            //使用writeValueAsString()方法将Java对象解析成json格式
//            String result = mapper.writeValueAsString(new ResponseEntity<Throwable>(InkStatus.CORE_OK,"token为null", throwable));
            String result = "登录失败\n";
            response.getWriter().print(result+e.toString());
        } catch (Exception e1) {

        }

        return false;
    }

    /**
     * 获取请求的token
     */
    private String getRequestToken(HttpServletRequest httpRequest){
        //从header中获取token
        String token = httpRequest.getHeader("auth-Token");

        //如果header中不存在token，则从参数中获取token
        if(token == null || token !=null && "null".equals(token) || token.isEmpty()){
            token = httpRequest.getParameter("authToken");
        }
        return token;
    }

}
